package com.xuchao.protocol;

import com.xuchao.message.Message;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageCodec;
import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.List;
import java.util.Objects;

/**
 * @Author xuchao
 * @Date:2024/1/18 11:08
 * @description 解码编码器
 * @Version 1.0
 */
@Slf4j
public class MessageCodec extends ByteToMessageCodec<Message> {
    @Override
    protected void encode(ChannelHandlerContext ctx, Message msg, ByteBuf out) throws Exception {
        //1. 4字节的魔数
        out.writeBytes(new byte[]{1,2,3,4});
        //2. 1字节的版本
        out.writeByte(1);
        //3. 1字节的序列化方式 0 jdk, 1 json  代表序列化的方式
        out.writeByte(0);
        //4. 1字节的指令类型
        out.writeByte(msg.getMessageType());
        //5 4字节的请求序号
        out.writeInt(msg.getSequenceId());
        //无意义的字节 凑够16位
        out.writeByte(0xff);
        //6 消息正文
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(msg);
        byte[] bytes = baos.toByteArray();
        //7 4字节的正文长度
        out.writeInt(bytes.length);
        //8 写入内容
        out.writeBytes(bytes);
    }

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        int magicNum = in.readInt();
        byte version = in.readByte();
        byte serializerType = in.readByte();
        byte messageType = in.readByte();
        int sequenceId = in.readInt();
        in.readByte();
        int length = in.readInt();
        byte[] bytes = new byte[length];
        in.readBytes(bytes);
        Message msg = null;
        if (serializerType == 0){
            ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
            msg = (Message) ois.readObject();
        }else {
            ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
            msg = (Message) ois.readObject();
        }
        log.debug("4字节的魔数:{}",magicNum);
        log.debug("1字节的版本:{}",version);
        log.debug("1字节的序列化方式 0 jdk, 1 json:{}",serializerType);
        log.debug("1字节的指令类型:{}",messageType);
        log.debug("4字节的请求序号:{}",sequenceId);
        log.debug("4字节的正文长度:{}",length);
        log.debug("消息正文:{}",msg.toString());
        out.add(msg);
    }
}
